/* Author: David McCoy dave.mccoy@cospandesign.com
 *
 *     This file is part of DLCM\SubServ.
 *
 *  DLCM\SubServ is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  DLCM\SubServ is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with DLCM\SubServ.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/* PaintComponent.java
 *
 * Main Paint, PainComponent was origionally written by
 * Timothy Boudreau and the PaintCanvas he wrote for the NetBeans Tutorial
 * Thanks!
 * 
 */

package com.cospandesign.gui.pubsub.widgets.GraphicsPanel;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;


public class PaintComponent extends JComponent implements MouseListener, MouseMotionListener {

    private int diam = 10;
    private Paint paint = Color.BLUE;
    private BufferedImage backingImage;
    private Point last;

    public PaintComponent() {
        addMouseListener(this);
        addMouseMotionListener(this);
        setBackground(Color.WHITE);
        putClientProperty(/*PrintManager.PRINT_PRINTABLE*/"print.printable", true);
    }

    public void setBrush(int diam) {
        this.diam = diam;
    }

    public void setDiam(int val) {
        this.diam = val;
    }

    public int getDiam() {
        return diam;
    }

    public void setPaint(Paint c) {
        this.paint = c;
    }

    public Paint getPaint() {
        return paint;
    }

    public Color getColor() {
        if (paint instanceof Color) {
            return (Color) paint;
        } else {
            return Color.BLACK;
        }
    }

    public void clear() {
        backingImage = null;
        repaint();
    }

    public BufferedImage getImage() {
        int width = Math.min(getWidth(), 1600);
        int height = Math.min(getHeight(),1200);
        if (backingImage == null || backingImage.getWidth() != width || backingImage.getHeight() != height) {
            BufferedImage old = backingImage;
            backingImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
            Graphics g = backingImage.getGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, width, height);
            if (old != null) {
                ((Graphics2D) backingImage.getGraphics()).drawRenderedImage(old,
                        AffineTransform.getTranslateInstance(0, 0));
            }
        }
        return backingImage;
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawRenderedImage(getImage(), AffineTransform.getTranslateInstance(0,0));
    }

    public void mouseClicked(MouseEvent e) {
        Point p = e.getPoint();
        Graphics2D g = getImage().createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setPaint(getPaint());
        g.setStroke(new BasicStroke(diam, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        if (last == null) {
            last = p;
        }
        g.drawLine(last.x, last.y, p.x, p.y);
        repaint(Math.min(last.x, p.x) - diam / 2 - 1,
                Math.min(last.y, p.y) - diam / 2 - 1,
                Math.abs(last.x - p.x) + diam + 2,
                Math.abs(last.y - p.y) + diam + 2);
        last = p;
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseDragged(MouseEvent e) {
        mouseClicked(e);
    }
    public void mouseMoved(MouseEvent e) {
        last = null;
    }

    JComponent createBrushSizeView() {
        return new BrushSizeView();
    }


    private class BrushSizeView extends JComponent {

        @Override
        public boolean isOpaque() {
            return true;
        }

        @Override
        public void paint(Graphics g) {
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setColor(getBackground());
            g.fillRect(0,0,getWidth(),getHeight());
            Point p = new Point(getWidth() / 2, getHeight() / 2);
            int half = getDiam() / 2;
            int diam = getDiam();
            g.setColor(getColor());
            g.fillOval(p.x - half, p.y - half, diam, diam);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(32, 32);
        }

        @Override
        public Dimension getMinimumSize() {
            return getPreferredSize();
        }

    }

    public void setRawImage(int width, int height, int[] argb){
        this.setBounds(this.getX(), this.getY(), width, height);
        backingImage.setRGB(0, 0, width, height, argb, 0, width);
        last = null;
        this.repaint();
    }
    public int[] getRawImage(){

        BufferedImage bi = getImage();
        return bi.getRGB(0, 0, this.getWidth(), this.getHeight(), null, 0, this.getWidth());
    }
    public int getImageWidth(){
        return getWidth();
    }
    public int getImageHeight(){
        return getHeight();
    }
    public int getImageSize(){
        return (getWidth() * getHeight());
    }

}
